package com.mybatis.demo;

import java.io.Serializable;
import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.ISelect;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mybatis.demo.util.ReflectUtil;

/**
 * 抽象Service
 * @author lisuo
 *
 * @param <Mapper>
 * @param <Model>
 */
@SuppressWarnings("unchecked")
public class AbstractService<Mapper extends BaseMapper<Model>,Model> {
	
	/** 注入mapper */
	@Autowired
	protected BaseMapper<Model> mapper;
	
	/** 注入批处理SqlSessionTemplate */
	@Autowired
	private SqlSessionTemplate batchSqlSessionTemplate;
	
	private Class<?> mapperClass;
	
	public AbstractService() {
		this.mapperClass = ReflectUtil.getSuperGenericType(this.getClass());
	}
	
	/**
	 * Insert 
	 * @param model
	 * @return
	 */
	public boolean insert(Model model){
		return mapper.insert(model) > 0;
	}
	
	/**
	 * Update
	 * @param model
	 * @return boolean
	 */
	public boolean update(Model model){
		return mapper.update(model) > 0;
	}
	
	/**
	 * Get By Id
	 * @param id
	 * @return Model
	 */
	public Model getById(Serializable id){
		return mapper.getById(id);
	}
	
	/**
	 * 原生的GetList
	 * @return
	 */
	public List<Model> getList(){
		return mapper.getList();
	}
	
	/**
	 * 分页查询List,不执行count语句
	 * @param pageNum
	 * @param pageSize
	 * @return
	 */
	public List<Model> getList(int pageNum,int pageSize){
		PageHelper.startPage(pageNum, pageSize, false);
		return mapper.getList();
	}
	
	/**
	 * 分页查询GetList
	 * @param pageNum
	 * @param pageSize
	 * @return
	 */
	public Page<Model> getListForPage(int pageNum,int pageSize){
		return PageHelper.startPage(pageNum, pageSize).doSelectPage(new ISelect() {
			@Override
			public void doSelect() {
				mapper.getList();
			}
		});
	}
	
	//这里的Transactionl一定要加，底层实现是命中SQL和Statement，必须使用的是同一个Connection
	/**
	 * 批量 insert
	 * @param models
	 * @return
	 */
	@Transactional
	public int batchcInsert(List<Model> models){
		int result = 0;
		BaseMapper<Model> modelMapper = (BaseMapper<Model>) batchSqlSessionTemplate.getMapper(mapperClass);
		for (Model model:models) {
			result += modelMapper.insert(model);
		}
		return result;
	}
	
	//这里的Transactionl一定要加，底层实现是命中SQL和Statement，必须使用的是同一个Connection
	/**
	 * 批量update
	 * @param models
	 * @return
	 */
	@Transactional
	public int batchcUpdate(List<Model> models){
		BaseMapper<Model> modelMapper = (BaseMapper<Model>) batchSqlSessionTemplate.getMapper(mapperClass);
		int result = 0;
		for (Model model:models) {
			result += modelMapper.update(model);
		}
		return result;
	}
	
	
	//自己想象......
}
